// 实现这个项目的构建任务
/* 
    1.分别写好处理html、css、js、img、font的任务
    2.将这些任务按需要创建组合任务
    3.创建web服务
    4.创建watch任务
    5.创建开发环境和生产环境任务
*/
const { src, dest, parallel, series, watch } = require('gulp')
const del = require('del')
const browserSync = require('browser-sync').create()

const DEST_DIR = 'dist'
const TEMP_DIR = '.temp'

// 加载插件
const loadPlugins = require('gulp-load-plugins')
// 加载所有插件，存放到plugins里
const plugins = loadPlugins()

/* const test = done => {
    console.log('可以自己实现功能，不一定都要用插件！！！')
    // 任务完成后一定要调用done方法，错误优先，要抛出错误用done(new Error('出错了'))
    done() 
} */

// del
const clean = () => {
    // 返回promise对象，也可以标记任务完成
    return del([DEST_DIR, TEMP_DIR])
}

// gulp-swig
const html = () => {
    // {base: 'src'} base指除了base指定的路径外其他路径原样输出
    return src('src/*.html', { base: 'src' })
        .pipe(plugins.swig({ defaults: { cache: false }, data: { /* 模板数据 */ } }))
        .pipe(dest(TEMP_DIR)) // 完成后会调done方法
        // .pipe(browserSync.reload({stream: true})) // 以流的方式往浏览器推， 用这种方式就可以不用 browserSync.init({ files: ["dist/**"] }
}
// gulp-sass
const style = () => {
    return src('src/assets/styles/*.scss', { base: 'src' })
        .pipe(plugins.sass({ outputStyle: 'expanded' }))
        .pipe(dest(TEMP_DIR))
}

// @babel/core @babel/preset-env gulp-babel
const js = () => {
    return src('src/assets/scripts/*.js', { base: 'src' })
        .pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
        .pipe(dest(TEMP_DIR))
}

// gulp-imagemin
const img = () => {
    return src('src/assets/images/**', { base: 'src' })
        .pipe(plugins.imagemin())
        .pipe(dest(DEST_DIR))
}

// gulp-imagemin
const font = () => {
    return src('src/assets/fonts/**', { base: 'src' })
        .pipe(plugins.imagemin())
        .pipe(dest(DEST_DIR))
}

const copy = () => {
    return src('public/**', { base: 'public' })
        .pipe(dest(DEST_DIR))
}

// gulp-useref
const useref = () => {
    return src(TEMP_DIR + '/*.html', {base: TEMP_DIR})
    // 去searchPath下找资源
    .pipe(plugins.useref({searchPath: [TEMP_DIR, '.']}))
    // gulp-htmlmin
    .pipe(plugins.if(/\.html$/, plugins.htmlmin({ collapseWhitespace: true, minifyCSS: true, minifyJS: true }))) 
    // gulp-clean-css
    .pipe(plugins.if(/\.css$/, plugins.cleanCss())) 
    // gulp-if gulp-uglify
    .pipe(plugins.if(/\.js$/, plugins.uglify())) 
    .pipe(dest(DEST_DIR))
}

// 所有需要编译的任务
const compile = parallel(html, style, js, img, font)

// 部署构建任务,1.清空 2.编译和拷贝 3.替换引用资源
const build = series(clean, parallel(compile, copy), useref)

// 开发任务
const serve = () => {

    watch('src/**/*.html', html)
    watch('src/assets/styles/*.scss', style)
    watch('src/assets/scripts/*.js', js)
    // 开发中可以不用构建这些文件，以提高构建效率
    // watch('src/assets/images/**', img)
    // watch('src/assets/fonts/**', font)
    // watch('public/**', copy)
    watch(['src/assets/images/**', 'src/assets/fonts/**', 'public/**'], browserSync.reload)

    browserSync.init({
        // 关闭右上角提示
        notify: false,
        port: 9527,
        /* open: false, */
        // 文件变化更新浏览器
        files: [TEMP_DIR + "/**"],
        server: {
            baseDir: [TEMP_DIR, DEST_DIR, "src", "public"],
            // 优先于baseDir
            routes: {
                '/node_modules': 'node_modules'
            }
        }
    });
}

// 启动开发环境，只构建html,css,js 其他文件使用路径去找到
const start = series(parallel(html, style, js), serve)


module.exports = {
    clean,
    start,
    build,
}